package com.guaoran.interview.spring.aop.config;

import com.guaoran.interview.spring.aop.service.ProgramAopService;
import com.guaoran.interview.spring.aop.service.ProgramAopServiceImpl;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import java.lang.reflect.Method;
import java.util.Arrays;

/**
 * @author : 孤傲然
 * @description : 编程式
 * @date :2020/1/5 18:19
 */
public class ProgramAop implements MethodBeforeAdvice , AfterReturningAdvice , MethodInterceptor , ThrowsAdvice {
    /**
     * 前置增强
     * @param method
     * @param args
     * @param target
     * @throws Throwable
     */
    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
//        System.out.println("before ... method:"+method+",args:"+ Arrays.toString(args)+",target:"+target);
    }

    /**
     * 后置返回通知
     * @param returnValue
     * @param method
     * @param args
     * @param target
     * @throws Throwable
     */
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
//        System.out.println("afterReturning ... returnValue:"+returnValue+",method:"+method+",args:"+ Arrays.toString(args)+",target:"+target);
    }

    /**
     * 环绕增强：实现MethodInterceptor接口
     * @param invocation
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
//        System.out.println("intercept ... invocation:"+invocation);
        return invocation.proceed();
    }

    /**
     * 配置抛出异常后通知
     * @param method
     * @param args
     * @param target
     * @param e
     */
    public void afterThrowing(Method method, Object[] args, Object target, Exception e) {
//        System.out.println("Throw exception:");
//        System.out.println("Target class name:" + target.getClass().getName());
//        System.out.println("Method name: " + method.getName());
//        System.out.println("Exception message:" + e.getMessage());
    }


    public static void main(String[] args) {
//        /**
//         * 测试前置增强和后置增强
//         */
//        ProxyFactory proxyFactory = new ProxyFactory();//创建代理工厂
//        proxyFactory.setTarget(new ProgramAopServiceImpl());//射入目标类对象
//        proxyFactory.addAdvice(new ProgramAop());//添加前置增强 、添加后置增强 、添加环绕增强
//        ProgramAopService programAopService = (ProgramAopService) proxyFactory.getProxy();//从代理工厂获取代理
//        programAopService.programAop();//调用代理的方法


        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:/program-aop-application-context.xml");
        ProgramAopService programAopService = (ProgramAopService) applicationContext.getBean("programAopService");
//        programAopService.programAop();
        programAopService.query();
        programAopService.queryAll();
        programAopService.save();
    }
}